﻿using PartsRetrospect.Comm;
using PartsRetrospect.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PartsRetrospect.Handle
{
    /// <summary>
    /// 1.定时查询本地未上传的气囊数据；
    /// 2.按列"VIN"、"Airbag"、"BodyNo"、 "ManyNO"、"Model"、"PosName"、 "VinMode"、"VinTime"、 "AirbagMode"; "AirbagTime"、"Station"、"Factory"、"Operator"、 "Valid"、 "InvalidTime"、"InvalidOperator"、"OPERATE_TYPE"、"EXTRACT_TIME"，列和数据之间都以1的unicode字符分隔进行数据组装
    /// 3.生成按DMP_VEHICLE_AIRBAG_" + 日期时间格式字符串+ "_" + 线号+计算机编号+ "_001.txt"格式命名的数据文件；
    /// 4.将文件以.gz为后缀进行压缩，然后上传至DMP平台文件服务器
    /// 5.按"VEHICLE_AIRBAG|" +记录条数+1的unicode字符组装行数
    /// 6.生成按airbag_" +日期时间格式字符串+ "_" +线号+计算机编号+ ".ok"格式命名的行数文件然后上传至DMP平台文件服务器
    /// 7.数据文件和行数必须同时上传完成方为成功，否则需要重新上传。
    /// 8.文件上传采用SFTP通讯协议。 
    /// </summary>
    public class FtpUploadHandler
    {
        /// <summary>
        /// 车间
        /// </summary>
        public string workshop { get; set; }
        /// <summary>
        /// 计算机编号(配置)
        /// </summary>
        public string computerNo { get; set; }
        /// <summary>
        /// 常量Convert.ToChar(1)
        /// </summary>
        public char chrSeparator = Convert.ToChar(1);
        /// <summary>
        /// 常量Convert.ToChar(10)
        /// </summary>
        public char chrBreak = Convert.ToChar(10);

        //FTP 地址、端口、用户名、密码、上传路径
        public string SFtpIp { get; set; }
        public string SFtpUser { get; set; }
        public string SFtpPwd { get; set; }
        public string UploadFilePath { get; set; } // "/etc/opt/gtmcTest";
        public int SFtpPort { get; set; } //26;

        public bool UploadData(List<AirbagModel> modelList,ref string errMesg)
        {
            try
            {
                //获取当前时间
                DateTime dateNow = DateTime.Now;
                //获取程序根路径
                string ps = System.Windows.Forms.Application.StartupPath;
                //原文件路径(根路径+固定路径)
                string strpath = ps + "\\uploadfile\\DMP_VEHICLE_AIRBAG_" + DateTime.Now.ToString("yyyyMMddTHHmmss") + "_" + workshop + computerNo + "_001.txt";
                //压缩文件路径
                string uppath = strpath + ".gz";
                //按规定格式生成TXT文件
                AddHeader(strpath);
                //把气囊信息写入TXT文件中
                AddDetail(modelList, strpath);
                //压缩文件
                new ClsGzip().CompressFile(strpath, uppath);
                //第一次上传
                if (UpFile(uppath,ref errMesg))
                {
                    string pathOK = ps + "\\uploadfile\\airbag_" + DateTime.Now.ToString("yyyyMMddTHHmmss") + "_" + workshop + computerNo + ".ok";
                    string writeOK = "VEHICLE_AIRBAG|" + modelList.Count.ToString() + chrBreak;
                    WriteTxt(pathOK, writeOK);
                    //第一次上传成功后第二次上传
                    if (UpFile(pathOK, ref errMesg))
                    {
                        return true;
                    }
                    else
                    {
                        //errMesg = "上传ok文件错误";
                        return false;
                    }
                }
                else
                {
                    //errMesg = "上传数据文件错误";
                    return false;
                }
            }
            catch (Exception ex)
            {
                errMesg = "上传异常： 异常信息" + ex.Message + " ----" + ex.StackTrace;
                return false;
            }
        }

        /// <summary>
        /// 生成带有固定报文头的TXT文件
        /// </summary>
        /// <param name="strPath">文件路径</param>
        public void AddHeader(string strPath)
        {
            string[] col = new string[16];
            string strHander = "#";
            col[0] = "VIN"; col[1] = "Airbag"; col[2] = "BodyNo"; col[3] = "ManyNO"; col[4] = "Model"; col[5] = "PosName"; col[6] = "VinMode"; col[7] = "VinTime";
            col[8] = "AirbagMode"; col[9] = "AirbagTime"; col[10] = "Station"; col[11] = "Factory"; col[12] = "Operator"; col[13] = "Valid"; col[14] = "InvalidTime"; col[15] = "InvalidOperator";
            for (int h = 0; h < 16; h++)
            {
                if (h < 15)
                    strHander = strHander + col[h] + chrSeparator;
                else
                    strHander = strHander + col[h];
            }
            strHander = strHander + chrSeparator + "OPERATE_TYPE" + chrSeparator + "EXTRACT_TIME" + chrBreak;
            WriteTxt(strPath, strHander);
        }

        /// <summary>
        /// 往TXT文件里写入报文
        /// </summary>
        /// <param name="modelList">数据体集合</param>
        /// <param name="strPath">文件路径</param>
        public void AddDetail(List<AirbagModel> modelList, string strPath)
        {
            string strcontent = "";
            foreach (var model in modelList)
            {
                string vin = model.VinCode;
                string Airbag = model.AirbagCode;
                string UploadType = model.UploadType;

                if (string.IsNullOrWhiteSpace(vin + Airbag)) continue;

                strcontent += ObjToStr(model.VinCode," ") + chrSeparator;                         //VIN码                  
                strcontent += ObjToStr(model.AirbagCode, " ") + chrSeparator;                     //气囊码
                strcontent += ObjToStr(model.BodyNo, " ") + chrSeparator;                         //车身码
                strcontent += ObjToStr(model.ManyNo, " ") + chrSeparator;                         //连番号
                strcontent += ObjToStr(model.Model, " ") + chrSeparator;                          //车型英文名称
                strcontent += ObjToStr(model.PosName, " ") + chrSeparator;                        //气囊位置
                strcontent += ObjToStr(model.OperateCarModel, " ") + chrSeparator;                //VIN码录入模式
                strcontent += ObjToStr(model.OperateCarDate, " ") + chrSeparator;                 //VIN码录入时间
                strcontent += ObjToStr(model.OperateAirbagModel, " ") + chrSeparator;             //气囊录入模式
                strcontent += ObjToStr(model.OperateAirbagDate, " ") + chrSeparator;               //气囊录入时间
                strcontent += ObjToStr(model.Station, " ") + chrSeparator;                         //位置
                strcontent += ObjToStr(model.Factory, " ") + chrSeparator;                         //车间编号
                strcontent += ObjToStr(model.Operator, " ") + chrSeparator;                        //操作人编号
                strcontent += ObjToStr(model.Valid, " ") + chrSeparator;                           //无效
                strcontent += ObjToStr(model.InvalidTime, " ") + chrSeparator;                     //无效时间
                strcontent += ObjToStr(model.InvalidOperator, " ") + chrSeparator;                 //无效操作人编号
                strcontent += ObjToStr(model.UploadType, " ") + chrSeparator;                      //上传类型
                strcontent += DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffffff");                 //时间
                strcontent += chrBreak;                   
            }
            strcontent += Convert.ToChar(13);
            WriteTxt(strPath, strcontent);
        }

        /// <summary>
        /// 生成TXT文件
        /// </summary>
        /// <param name="strPath">生成路径</param>
        /// <param name="txt">文本内容</param>
        public void WriteTxt(string strPath, string txt)
        {
            StreamWriter sw = new StreamWriter(strPath, true, new UTF8Encoding(false));
            sw.Write(txt);
            sw.Close();
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="strFilePath">文件路径</param>
        /// <param name="errMesg">错误信息</param>
        /// <returns>是否成功</returns>
        public bool UpFile(string strFilePath,ref string errMesg)
        {
            try
            {
                SecureFileTransfer transfer = SecureFileTransfer.getInstance(SFtpIp, SFtpPort, SFtpUser, SFtpPwd);
                bool boolReturn = transfer.putFile(strFilePath, UploadFilePath);
                if (boolReturn)
                {
                    //LableStateChange(2);
                }
                else
                {
                    errMesg ="上传错误";
                    //LableStateChange(1);
                }
                return boolReturn;
            }
            catch (Exception ex)
            {
                errMesg = "上传错误" + ex.Message + " ----" + ex.StackTrace;
                //LableStateChange(1);
                return false;
            }
        }

        public string ObjToStr(object obj, string dfault = "")
        {
            if (obj == DBNull.Value) return dfault;
            if (obj == null) return dfault;
            string rts = obj.ToString();
            if (string.IsNullOrWhiteSpace(rts)) return dfault;
            return obj.ToString();
        }
    }
}
